from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from django.contrib.auth import authenticate, login, logout
from django.utils import timezone
from django.db.models import Q, Count, Sum
from django.views.decorators.csrf import csrf_exempt
from .models import User, UserBadge, Badge, UserMessage, SysInfo, TopPostPermission, PendingUserRegistration
from apps.articles.models import Like
from datetime import datetime
from .serializers import (
    UserRegistrationSerializer, UserLoginSerializer, UserInfoSerializer,
    UserUpdateSerializer, UserBadgeSerializer, UserMessageSerializer,
    PendingUserRegistrationSerializer
)
from apps.articles.models import Article
from utils.response import success_response, error_response
from utils.oss_utils import get_oss_uploader
from utils.email_utils import send_and_store_verification_code, verify_code
import logging
import re

logger = logging.getLogger(__name__)


@api_view(['POST'])
@permission_classes([AllowAny])
def send_verification_code(request):
    """发送邮箱验证码"""
    try:
        email = request.data.get('email')
        
        if not email:
            return error_response("Email cannot be empty")
        
        # 验证邮箱格式
        email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        if not re.match(email_pattern, email):
            return error_response("Email format incorrect")
        
        # 检查邮箱是否在白名单中
        from .models import AllowedEmail
        if not AllowedEmail.is_email_allowed(email):
            return error_response("This email is not allowed to register")
        
        # 检查邮箱是否已被注册
        if User.objects.filter(email=email).exists():
            return error_response("This email has already been registered")
        
        # 发送验证码
        success, code = send_and_store_verification_code(email)
        
        if success:
            return success_response(message="Verification code sent successfully, please check your email")
        else:
            return error_response("Verification code send failed , please try again")
            
    except Exception as e:
        logger.error(f"Failed to send verification code: {e}")
        return error_response("Failed to send verification code, please try again")


@api_view(['POST'])
@permission_classes([AllowAny])
def register(request):
    """用户注册"""
    try:
        email = request.data.get('email')
        verification_code = request.data.get('verificationCode')
        
        if not email or not verification_code:
            return error_response("Email and verification code cannot be empty")
        
        # 验证验证码
        if not verify_code(email, verification_code):
            return error_response("Verification code error or expired")
        
        # 验证通过，进行注册
        serializer = UserRegistrationSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            return success_response(message="registered successfully")
        return error_response(message=str(serializer.errors))
        
    except Exception as e:
        logger.error(f"User registration failed: {e}")
        return error_response("Registration failed, please try again")


@api_view(['POST'])
@permission_classes([AllowAny])
def send_external_verification_code(request):
    """为外部用户注册发送邮箱验证码"""
    try:
        email = request.data.get('email')
        
        if not email:
            return error_response("Email cannot be empty")
        
        # 验证邮箱格式
        email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        if not re.match(email_pattern, email):
            return error_response("Email format incorrect")
        
        # 检查邮箱是否已被注册（包括正式用户和待审核申请）
        if User.objects.filter(email=email).exists():
            return error_response("This email has already been registered")
        
        # 检查是否已经有待审核的申请
        if PendingUserRegistration.objects.filter(email=email, status=0).exists():
            return error_response("There is already a pending registration for this email")
        
        # 发送验证码
        success, code = send_and_store_verification_code(email)
        
        if success:
            logger.info(f"External user verification code sent to: {email}")
            return success_response(message="Verification code sent successfully, please check your email")
        else:
            return error_response("Verification code send failed, please try again")
            
    except Exception as e:
        logger.error(f"Failed to send external user verification code: {e}")
        return error_response("Failed to send verification code, please try again")


@api_view(['POST'])
@permission_classes([AllowAny])
def user_login(request):
    """用户登录"""
    serializer = UserLoginSerializer(data=request.data)
    if serializer.is_valid():
        user = serializer.validated_data['user']
        
        # 更新最后登录时间
        user.last_login_time = timezone.now()
        user.save()
        
        # 创建或获取token
        token, created = Token.objects.get_or_create(user=user)
        
        # 登录用户
        login(request, user)
        
        # 检查用户是否有置顶权限
        has_top_post_permission = False
        if user.is_staff or user.is_superuser:
            has_top_post_permission = True
        else:
            has_top_post_permission = TopPostPermission.objects.filter(
                user=user,
                is_active=True
            ).exists()
        
        return success_response({
            "nickName": user.nickname,
            "userId": str(user.user_id),
            "avatar": user.avatar,
            "token": token.key,
            "hasTopPostPermission": has_top_post_permission,
            "isSuperuser": user.is_superuser
        })
    return error_response(message=serializer.errors)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def user_logout(request):
    """用户退出登录"""
    try:
        # 删除token
        request.user.auth_token.delete()
    except:
        pass
    
    logout(request)
    return success_response(message="Logout successful")


@api_view(['POST'])
@permission_classes([AllowAny])
def get_user_info(request):
    """获取用户信息"""
    user_id = request.data.get('userId')
    if not user_id:
        return error_response(message="User ID cannot be empty")
    
    try:
        user = User.objects.get(user_id=user_id)
        serializer = UserInfoSerializer(user)
        return success_response(serializer.data)
    except User.DoesNotExist:
        return error_response(message="User does not exist")


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def update_user_info(request):
    """修改用户信息"""
    # 创建可变的数据副本
    data = request.data.copy()

    if data.get('removeAvatar') == True:
        data['avatar'] = ""  # 设置为空字符串，触发默认头像逻辑
    
    serializer = UserUpdateSerializer(request.user, data=data, partial=True)
    if serializer.is_valid():
        updated_user = serializer.save()
        # 返回更新后的用户信息，使用UserInfoSerializer格式化数据
        user_serializer = UserInfoSerializer(updated_user)
        return success_response(data=user_serializer.data, message="Update successful")
    return error_response(message=str(serializer.errors))


@api_view(['POST'])
@permission_classes([AllowAny])
def get_user_badges(request):
    """获取用户成就"""
    user_id = request.data.get('userId')
    if not user_id:
        return error_response(message="User ID cannot be empty")
    
    try:
        user = User.objects.get(user_id=user_id)
        user_badges = UserBadge.objects.filter(user=user).select_related('badge')
        
        badge_list = []
        for user_badge in user_badges:
            badge_list.append({
                'id': user_badge.id,
                'badgeId': user_badge.badge.badge_id,
                'name': user_badge.badge.name,
                'img': user_badge.badge.img,
                'description': user_badge.badge.description
            })
        
        return success_response({'badgeList': badge_list})
    except User.DoesNotExist:
        return error_response(message="User does not exist")


@api_view(['POST'])
@permission_classes([AllowAny])
def get_user_posts(request):
    """获取用户发帖"""
    user_id = request.data.get('userId')
    page_no = int(request.data.get('pageNo', 1))
    page_size = int(request.data.get('pageSize', 15))
    
    if not user_id:
        return error_response(message="User ID cannot be empty")
    
    try:
        user = User.objects.get(user_id=user_id)
        articles = Article.objects.filter(user=user).order_by('-post_time')
        
        # 计算分页
        total_count = articles.count()
        start_index = (page_no - 1) * page_size
        end_index = start_index + page_size
        page_articles = articles[start_index:end_index]
        
        article_list = []
        for article in page_articles:
            article_list.append({
                'articleId': article.article_id,
                'pBoardId': article.p_board.p_board_id,
                'pBoardName': article.p_board_name,
                'boardId': article.board.board_id if article.board else None,
                'boardName': article.board_name,
                'userId': article.user.user_id,
                'nickName': article.nick_name,
                'avatar': article.user.avatar,
                'title': article.title,
                'cover': article.cover,
                'content': '',
                'postTime': article.post_time.strftime('%Y-%m-%d %H:%M:%S'),
                'goodCount': article.good_count,
                'commentCount': article.comment_count,
                'topType': article.top_type
            })
        
        # 计算总页数
        page_total = (total_count + page_size - 1) // page_size
        
        return success_response({
            'totalCount': total_count,
            'pageSize': page_size,
            'pageNo': page_no,
            'pageTotal': page_total,
            'list': article_list
        })
    except User.DoesNotExist:
        return error_response(message="User does not exist")


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def upload_avatar(request):
    """上传用户头像"""
    try:
        # 检查是否有上传的文件
        if 'avatar' not in request.FILES:
            return error_response(message="Please select an avatar to upload")
        
        avatar_file = request.FILES['avatar']
        
        # 验证文件类型
        allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
        if avatar_file.content_type not in allowed_types:
            return error_response(message=f"Unsupported image format, supported formats: {', '.join(allowed_types)}")
        
        # 验证文件大小（限制5MB）
        max_size = 5 * 1024 * 1024  # 5MB
        if avatar_file.size > max_size:
            return error_response(message="Avatar size cannot exceed 5MB")
        
        # 验证文件名
        if not avatar_file.name:
            return error_response(message="File name cannot be empty")
        
        # 获取OSS上传器
        uploader = get_oss_uploader()
        if not uploader:
            logger.error("OSS uploader initialization failed")
            return error_response(message="Avatar upload service is temporarily unavailable", code=500)
        
        # 上传到OSS
        avatar_url = uploader.upload_file(avatar_file, folder='avatar')
        
        if avatar_url:
            # 更新用户头像
            request.user.avatar = avatar_url
            request.user.save()
            
            logger.info(f"User {request.user.user_id} avatar upload successful: {avatar_url}")
            return success_response({
                'avatarUrl': avatar_url,
                'fileName': avatar_file.name,
                'fileSize': avatar_file.size
            }, message="Avatar upload successful")
        else:
            logger.error(f"User {request.user.user_id} avatar upload failed")
            return error_response(message="Avatar upload failed, please try again", code=500)
            
    except Exception as e:
        logger.error(f"Avatar upload exception: {e}")
        return error_response(message="Avatar upload exception, please try again", code=500)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def get_message_count(request):
    """获取用户消息数"""
    messages = UserMessage.objects.filter(received_user_id=str(request.user.user_id), status=0)
    
    total = messages.count()
    sys_count = messages.filter(message_type=0).count()
    reply_count = messages.filter(message_type__in=[1, 2]).count()
    like_count = messages.filter(message_type__in=[3, 4]).count()
    
    return success_response({
        'total': total,
        'sys': sys_count,
        'reply': reply_count,
        'like': like_count
    })


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def get_unread_message_count(request):
    """获取用户未读消息数量"""
    messages = UserMessage.objects.filter(received_user_id=str(request.user.user_id), status=0)
    
    total_unread = messages.count()
    sys_unread = messages.filter(message_type=0).count()
    reply_unread = messages.filter(message_type__in=[1, 2]).count()
    like_unread = messages.filter(message_type__in=[3, 4]).count()
    
    return success_response({
        'totalUnread': total_unread,
        'sysUnread': sys_unread,
        'replyUnread': reply_unread,
        'likeUnread': like_unread
    })


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def get_message_list(request):
    """获取用户消息列表"""
    code = request.data.get('code')
    page_no = int(request.data.get('pageNo', 1))
    page_size = int(request.data.get('pageSize', 50))
    
    # 如果是系统消息（code=0），从sys_info表获取
    if code == 0:
        sys_infos = SysInfo.objects.all().order_by('-sys_id')
        
        # 简单分页
        start = (page_no - 1) * page_size
        end = start + page_size
        page_sys_infos = sys_infos[start:end]
        
        # 构造系统消息数据
        sys_message_list = []
        for sys_info in page_sys_infos:
            sys_message_list.append({
                'messageId': sys_info.sys_id,
                'articleId': '',
                'articleTitle': '',
                'commentId': '',
                'sendUserId': '',
                'sendNickName': 'System',
                'sendUserAvatar': '',
                'messageType': 0,
                'content': sys_info.content,
                'time': '',
                'readStatus': 1  # 系统消息默认已读
            })
        
        response_data = {
            'totalCount': sys_infos.count(),
            'pageSize': page_size,
            'pageNo': page_no,
            'pageTotal': (sys_infos.count() + page_size - 1) // page_size,
            'list': sys_message_list
        }
        
        return success_response(response_data)
    
    # 其他类型消息从UserMessage表获取
    messages = UserMessage.objects.filter(received_user_id=str(request.user.user_id))
    
    # 根据code筛选消息类型
    if code == 1:  # 回复消息
        messages = messages.filter(message_type__in=[1, 2])
    elif code == 2:  # 点赞消息
        messages = messages.filter(message_type__in=[3, 4])
    
    messages = messages.order_by('-create_time')
    
    # 简单分页
    start = (page_no - 1) * page_size
    end = start + page_size
    page_messages = messages[start:end]

    serializer = UserMessageSerializer(page_messages, many=True)

    response_data = {
        'totalCount': messages.count(),
        'pageSize': page_size,
        'pageNo': page_no,
        'pageTotal': (messages.count() + page_size - 1) // page_size,
        'list': serializer.data
    }

    # 标记为已读
    if code == 1:
        UserMessage.objects.filter(
            received_user_id=str(request.user.user_id),
            message_type__in=[1, 2],
            status=0
        ).update(status=1)
    elif code == 2:
        UserMessage.objects.filter(
            received_user_id=str(request.user.user_id),
            message_type__in=[3, 4],
            status=0
        ).update(status=1)

    return success_response(response_data)


@api_view(['POST'])
@permission_classes([AllowAny])
def get_daily_top_users(request):
    """获取当日最热门的5位用户"""
    try:
        today = timezone.now().date()
        today_start = datetime.combine(today, datetime.min.time())
        today_end = datetime.combine(today, datetime.max.time())
        
        # 查询当日的点赞记录，统计每个用户当日发布文章获得的点赞数
        daily_user_likes = Like.objects.filter(
            like_type=0,  # 文章点赞
            create_time__range=[today_start, today_end],
            author_user_id__isnull=False
        ).values('author_user_id').annotate(
            daily_like_count=Count('like_id')
        ).order_by('-daily_like_count')
        
        # 获取当日有点赞的用户ID
        daily_user_ids = []
        for item in daily_user_likes:
            if item['author_user_id']:
                try:
                    user_id = int(item['author_user_id'])
                    daily_user_ids.append(user_id)
                except (ValueError, TypeError):
                    continue
        
        if len(daily_user_ids) >= 5:
            # 如果当日有点赞的用户数量>=5，直接取前5个
            top_user_ids = daily_user_ids[:5]
            users = User.objects.filter(user_id__in=top_user_ids)
            
            # 手动排序，保持原有顺序
            users_dict = {user.user_id: user for user in users}
            sorted_users = [users_dict[user_id] for user_id in top_user_ids if user_id in users_dict]
            
        else:
            # 如果当日有点赞的用户数量<5，需要补充其他用户
            # 先获取当日有点赞的用户
            daily_users = User.objects.filter(user_id__in=daily_user_ids) if daily_user_ids else []
            
            # 手动排序当日用户
            daily_users_dict = {user.user_id: user for user in daily_users}
            sorted_daily_users = [daily_users_dict[user_id] for user_id in daily_user_ids if user_id in daily_users_dict]
            
            # 再获取其他用户
            remaining_count = 5 - len(daily_user_ids)
            
            # 统计每个用户的总点赞数
            total_user_likes = Like.objects.filter(
                like_type=0,
                author_user_id__isnull=False
            ).exclude(
                author_user_id__in=[str(uid) for uid in daily_user_ids]  # 转换为字符串进行排除
            ).values('author_user_id').annotate(
                total_like_count=Count('like_id')
            ).order_by('-total_like_count')[:remaining_count]
            
            other_user_ids = []
            for item in total_user_likes:
                if item['author_user_id']:
                    try:
                        user_id = int(item['author_user_id'])
                        other_user_ids.append(user_id)
                    except (ValueError, TypeError):
                        continue
            
            other_users = User.objects.filter(user_id__in=other_user_ids) if other_user_ids else []
            
            # 合并用户列表
            sorted_users = sorted_daily_users + list(other_users)
            
            # 如果仍然不足5个用户，补充任意用户
            if len(sorted_users) < 5:
                existing_user_ids = [user.user_id for user in sorted_users]
                additional_count = 5 - len(sorted_users)
                
                additional_users = User.objects.exclude(
                    user_id__in=existing_user_ids
                ).order_by('user_id')[:additional_count]
                
                sorted_users.extend(list(additional_users))
        
        # 构建返回数据
        user_list = []
        for user in sorted_users:
            # 计算当日点赞数
            daily_count = Like.objects.filter(
                author_user_id=str(user.user_id),
                like_type=0,
                create_time__range=[today_start, today_end]
            ).count()
            
            # 计算总点赞数
            total_count = Like.objects.filter(
                author_user_id=str(user.user_id),
                like_type=0
            ).count()
            
            user_list.append({
                'userId': user.user_id,
                'nickName': user.nickname,
                'avatar': user.avatar,
                'dailyLikeCount': daily_count,
                'totalLikeCount': total_count
            })
        
        return success_response({
            'list': user_list
        })
        
    except Exception as e:
        logger.error(f"Failed to get daily top users: {e}")
        import traceback
        logger.error(f"Traceback: {traceback.format_exc()}")
        return error_response("Failed to obtain daily top users, please try again")


@api_view(['POST'])
@permission_classes([AllowAny])
def external_user_registration(request):
    """外来用户注册申请接口"""
    try:
        email = request.data.get('email')
        verification_code = request.data.get('verificationCode')
        
        if not email or not verification_code:
            return error_response("Email and verification code cannot be empty")
        
        # 验证验证码
        if verify_code(email, verification_code):
            # 验证通过，进行注册申请
            serializer = PendingUserRegistrationSerializer(data=request.data)
            if serializer.is_valid():

                pending_registration = serializer.save()
                
                logger.info(f"New external user registration application: {pending_registration.email}")
                
                return success_response(
                    data={
                        "application_id": pending_registration.id,
                        "email": pending_registration.email,
                        "nickname": pending_registration.nickname,
                        "status": "pending"
                    },
                    message="Registration application submitted successfully, please wait for review"
                )
            else:
                error_messages = []
                for field, errors in serializer.errors.items():
                    for error in errors:
                        error_messages.append(f"{field}: {error}")
                
                return error_response(
                    message="; ".join(error_messages),
                    code=400
                )
        else:
            return error_response("Verification code error or expired")
            
    except Exception as e:
        logger.error(f"External user registration error: {str(e)}")
        return error_response(
            message="Registration application failed, please try again",
            code=500
        )


@api_view(['POST'])
@permission_classes([AllowAny])
def upload_support_image(request):
    """上传support图片到阿里云OSS"""
    try:
        # 检查是否有上传的文件
        if 'image' not in request.FILES:
            return error_response(message="Please select an image to upload")
        
        image_file = request.FILES['image']
        
        # 验证文件类型
        allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
        if image_file.content_type not in allowed_types:
            return error_response(message=f"Unsupported image format. Supported formats: {', '.join(allowed_types)}")
        
        # 验证文件大小（限制10MB）
        max_size = 10 * 1024 * 1024  # 10MB
        if image_file.size > max_size:
            return error_response(message="Image size cannot exceed 10MB")
        
        # 验证文件名
        if not image_file.name:
            return error_response(message="File name cannot be empty")
        
        # 获取OSS上传器
        uploader = get_oss_uploader()
        if not uploader:
            logger.error("OSS uploader initialization failed")
            return error_response(message="Image upload service is temporarily unavailable", code=500)
        
        # 上传到OSS，使用support文件夹
        image_url = uploader.upload_file(image_file, folder='support')
        
        if image_url:
            logger.info(f"Support image uploaded successfully: {image_url}")
            return success_response({
                'imageUrl': image_url,
                'fileName': image_file.name,
                'fileSize': image_file.size
            }, message="Support image uploaded successfully")
        else:
            logger.error("Support image upload failed")
            return error_response(message="Image upload failed, please try again", code=500)
            
    except Exception as e:
        logger.error(f"Support image upload exception: {e}")
        return error_response(message="Image upload exception, please try again", code=500)


@api_view(['POST'])
@permission_classes([AllowAny])
def delete_support_image(request):
    """删除support图片"""
    try:
        image_url = request.data.get('image_url')
        
        if not image_url:
            return error_response("Image URL cannot be empty")
        
        # 获取OSS上传器
        oss_uploader = get_oss_uploader()
        if not oss_uploader:
            return error_response("OSS service initialization failed")
        
        # 删除OSS中的文件
        success = oss_uploader.delete_file(image_url)
        
        if success:
            logger.info(f"Support image deleted successfully: {image_url}")
            return success_response("Support image deleted successfully")
        else:
            return error_response("Image deletion failed")

    except Exception as e:
        logger.error(f"Delete support image failed: {e}")
        return error_response("Deletion failed, please try again")